/*
 * @Description: 错误状态处理
 * @Author: James324
 * @Date: 2023-08-22 13:51:33
 * @LastEditors: James324
 * @LastEditTime: 2024-04-01 17:28:09
 */
import { AxiosResponse } from 'axios';
import { removeToken, toLogin } from '@/utils';
import { message } from '@/components/q-message/message';
import { PASS_FAIL_URLS, ERR_RETRY_AND_DELAY, CODE_LIST } from './config';

/**
 * 请求失败后的错误统一处理
 * @param {Number} status 请求失败的状态码
 */
export const errorHandle = (status: number, other: string = '其他错误错误') => {
    // 状态码判断
    switch (status) {
        case 302:
            message.error('接口重定向了！');
            break;
        case 400:
            message.error('发出的请求有错误，服务器没有进行新建或修改数据的操作');
            break;
        // 401: 未登录
        // 未登录则跳转登录页面，并携带当前页面的路径
        // 在登录成功后返回当前页面，这一步需要在登录页操作。
        case 401: //重定向
            message.error('token: 登录失效');
            removeToken();
            toLogin();
            break;
        // 403 token过期
        // 清除token并跳转登录页
        case 403:
            message.error('登录过期,用户得到授权，但是访问是被禁止的');
            removeToken();
            setTimeout(() => {
                toLogin();
            }, 500);
            break;
        case 404:
            message.error('网络请求不存在');
            break;
        case 406:
            message.error('请求的格式不可得');
            break;
        case 408:
            message.error(' 请求超时！');
            break;
        case 410:
            message.error('请求的资源被永久删除，且不会再得到的');
            break;
        case 422:
            message.error('当创建一个对象时，发生一个验证错误');
            break;
        case 500:
            message.error('服务器发生错误，请检查服务器');
            break;
        case 502:
            message.error('网关错误');
            break;
        case 503:
            message.error('服务不可用，服务器暂时过载或维护');
            break;
        case 504:
            message.error('网关超时');
            break;
        default:
            message.error(other + status);
    }
};

export const errorReqTimeout = async function (This: any, err: any, res: AxiosResponse) {
    const [RETRY_COUNT, RETRY_DELAY] = ERR_RETRY_AND_DELAY;
    const config = err.config;

    if (config && RETRY_COUNT && !CODE_LIST.includes(res.status)) {
        // 设置用于跟踪重试计数的变量
        config.__retryCount = config.__retryCount || 1;

        // 检查是否已经把重试的总数用完
        if (config.__retryCount >= RETRY_COUNT) {
            return Promise.reject(res || { message: err.message });
        }
        // 增加重试计数
        config.__retryCount++;
        // 创造新的Promise来处理指数后退
        const backoff = new Promise<void>(resolve => {
            setTimeout(() => {
                resolve();
            }, RETRY_DELAY || 1);
        });
        // instance重试请求的Promise
        return await backoff.then(async () => {
            return await This.instance.request(config);
        });
    }
};

/**
 * 错误捕获，处理错误提示
 */
const someList = (url: string) => PASS_FAIL_URLS.some(item => url.includes(item));
export const handleErrorMessage = (res: any, errMsg?: string) => {
    const messages = res.data?.msg || errMsg || '系统出错，请联系管理员！';
    if (!res.config?.headers.hideMsg && !someList(res.config?.url)) {
        message.error(messages);
    }
};
